1. Technical Field
The present invention relates in general to a system and method for reducing memory leaks in virtual machine programs. More specifically, the present invention relates to a system and method for using a compiler to add nullification statements in a program.
2. Description of the Related Art
Middleware environments, such as that provided by a Java Virtual Machine (JVM), often use a heap to store objects created in the environment. The heap stores objects created by an application running in the middleware environment. Garbage collection is the process of automatically freeing objects from the heap that are no longer needed by the application. This reduces the burden of memory management placed on the programmer.
However, garbage collection is not a panacea. Long running middleware applications remain susceptible to failures induced by “memory leaks.” A memory leak is a term used to describe error conditions that arise when programs allocate memory that is not reclaimed. As described above, garbage collection reclaims memory after the last reference to the memory is no longer “reachable” from a known set of “roots,” wherein the roots include things such as processor registers and memory locations containing references to heap objects, such as those used to hold the program stacks. Consequently, garbage collection may leave objects in the heap that are irrelevant (i.e., no longer needed) to the future of the computation but are still reachable from at least one object.
Some of these reachable but irrelevant objects arise from local variables that exist in the activation records of a program. The activation record includes variables (i.e., objects references) that are passed to a procedure from another procedure or routine as well as local variables that are declared within the program. These procedures may be long-lived and include memory hungry processing. Therefore, freeing objects that are no longer used is often vital to avoiding memory problems.
One approach to freeing objects is for the programmer to explicitly nullify a variable that will no longer be used in the program. A first challenge to this approach is that it nullifies the benefits of using garbage collection, as the programmer is forced to consider memory management issues even when such considerations may not be necessary. This is not a common practice with programmers of middleware applications, except when memory problems arise. A second challenge is completeness. Namely, identifying all nullifiable variables may be difficult and time consuming for a programmer. A third challenge is correctness: when attempting to nullify the variables, the programmer may introduce errors by prematurely nullifying a variable.
A fourth challenge regards single-assignment semantics. More specifically, a programmer may use variables and parameters with single-assignment semantics, such as using the “const” keyword in the C programming language, or using the “final” attribute in a Java program. Single-assignment semantics are used to prevent certain types of programming errors as well as to communicate a variable's use clearly to other programmers and the compiler. A programmer desiring to use single-assignment cannot use nullification, as the nullification statement will be seen by the compiler as a second assignment, violating the single-assignment semantic. The programmer must therefore choose, for every variable, whether to use single-assignment or variable nullification, thus losing the benefits of using both techniques simultaneously.
Another challenge is that a compiler may actually be responsible for setting up a variable to reference an object as well as including the variable in the activation record of a program. In such situations, the programmer would not know the name of the variable or object being passed as a result of the compiler and, therefore, would not be able to include a statement nullifying the object or variable after it is no longer used.
FIG. 1 is a prior art diagram showing how prior art compilers, including Just-in-Time (JIT) compilers, do not nullify variables after the last use of such variables. Garbage collector 100 is a process (i.e., a software routine) that reclaims memory from heap 110. When invoked, garbage collector 100 determines which objects residing in the heap are no longer accessible (“reachable”) from other objects (“roots”), such as the program stack 125. Program stack 125 includes a start of the procedure 130, often identified by a left brace ({). The program stack includes activation records 140 that include parameters that are passed to the program as well as locally declared variables 150. Variables included in the activation records refer to objects that are stored in memory that is included in heap 110. Program stack 125 also includes statements that use objects and variables 160. Such statements may retrieve data from objects and variables, store data in the objects and variables, or use the objects and variables in computations or to call other programs or procedures.
At various points in the program, a last use of a variable that references an object is made. One of these points is statement 170. While only one point is shown in program stack 125, it will be understood by those skilled in the art that many such points may exist in a given program when particular variables are no longer used (i.e., some variables may no longer be used while other variables continue to be used). Even though the variables are no longer used, program stack 125 continues to reference the unused variables. The continued reference by such variables to such no-longer-used objects results in garbage collector 100 maintaining (i.e., not removing) the memory used by the no-longer-used objects within heap 110, notwithstanding the fact that there may be no objects needing the objects and variables. In the example shown, program stack 125 performs memory hungry computation 180. Even if the middleware environment, such as a Java Virtual Machine, needs additional memory to perform the computation, it is unable to identify the no-longer-used objects as “garbage” until after the computation is performed (i.e., at the end of the procedure 180 which is often identified with a closing brace (})).
What is needed, therefore, is a system and method for automatically nullifying variables that are no longer used by a program. What is further needed is a modification of the compiler to automatically nullify variables both referenced by the programmer as well as those included by the compiler.